package threadDemo.productAndCosumerDemo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.*;

public class DemoMain {
    private static final Logger logger = LoggerFactory.getLogger(DemoMain.class);

    //设置核心线程数为5 max=50 阻塞队列为linkedQueue
    private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 1, TimeUnit.MINUTES, new LinkedBlockingDeque<>());

    public static void main(String[] args) {

        StopWatch stopWatch = new StopWatch(UUID.randomUUID().toString());
        stopWatch.start("生产者启动");

        //列表初始容量，减少扩容次数
        List<Future<String>> futureList = new ArrayList<>(2000 * 10);
        //阻塞队列设置的最大100*100（启动100个生产者 每个生产者放100个dto）
        BlockingQueue<ProAndConDto> blockingQueue = new LinkedBlockingQueue<>(100 * 100);
        try {
            //开启100个生产者线程-生产者
            for (int i = 100; i > 0; i--) {
                Producer task = new Producer(blockingQueue);
                futureList.add((Future<String>) threadPoolExecutor.submit(task));
            }

        } finally {
            threadPoolExecutor.shutdown();
        }
        stopWatch.stop();

        stopWatch.start("消费者启动");
        //获取数据并消费数据-消费者
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        try {
            executorService.submit(new Consumer(blockingQueue));
        } finally {
            executorService.shutdown();
        }

        //生产者任务执行完后插入结束标识，此方法阻塞主线程，需在创建完生产者和消费者任务后执行
        for (Future<String> future : futureList) {
            try {
                future.get();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //插入结束标识
        try {
            blockingQueue.put(new ProAndConDto(-1));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        stopWatch.stop();
        System.out.println(stopWatch.prettyPrint());

    }


}
